package hehe.log.base;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 日志格式化
 *<B>说明：</B>
 *<pre>
 * 略
 *</pre>
 *<B>示例：</B>
 *<pre>
 *  略
 *</pre>
 *<B>日志：</B>
 *<pre>
 *  略
 *</pre>
 *<B>注意事项：</B>
 *<pre>
 *  略
 *</pre>
 */
public class Format
{
    /**
     * 是否追加换行符号
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    protected boolean appendLinebreak = true;

    protected String formatTemplate = "";

    protected String replaceTemplate = "";

    // 消息标签
    public static final String MESSAGE_ALIAS = "m";
    // 输出优先级
    public static final String LEVEL_ALIAS = "l";
    // 输出日志的类路径
    public static final String CLASS_PATH_alias = "c";
    // 输出产生该日志事件的线程名
    public static final String CURRENT_THREAD_ALIAS = "t";
    // 输出一个回车换行符
    public static final String LINE_SEPARATOR_ALIAS = "n";
    // 当前日期格式
    public static final String DATETIME_ALIAS = "d";

    protected Map<String,String> templateParams = new HashMap<>();

    protected Map<String,int[]> templateParamPos = new HashMap<>();


    public Format()
    {

    }

    public Format(String formatTemplate)
    {
        this.formatTemplate = formatTemplate;
        this.replaceTemplate = formatTemplate;
        this.templateParams = this.parseTemplate();
    }

    /**
     * 解析输出模板
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     */
    protected Map<String,String> parseTemplate()
    {
        //{d} <(\w+):?([^>]+)?> {(\w+)}
        // <controller:\w+>/<id:\d+> 将controller,id 提取出来
        Matcher templateMatcher = Pattern.compile("\\{(\\w+)\\}")
                .matcher(this.formatTemplate);
        // 定义参数匹配项
        String name;
        Map<String,String> templateParams = new HashMap<>();

        StringBuffer replaceTemplate = new StringBuffer(this.formatTemplate);

        while (templateMatcher.find()){
            name = templateMatcher.group(1);
            // 检验是否存在冒号:
            if (name.indexOf(":") == -1) {
                templateParams.put(name,"");
            } else {
                String[] params = name.split(":");
                templateParams.put(params[0],params[1]);
                name = params[0];
            }

            replaceTemplate.replace(templateMatcher.start(),templateMatcher.end(),"{" + name + "}");
        }

        this.replaceTemplate = replaceTemplate.toString();

        return templateParams;
    }

    protected String getLinebreak()
    {
        return System.getProperty("line.separator");
    }

    public String parse(Message message)
    {
        if (this.formatTemplate.equals("")) {
            return message.getMsg() + this.getLinebreak();
        }

        Map<String,String> params = message.getMessageParams();
        params.put(LINE_SEPARATOR_ALIAS,this.getLinebreak());

        return this.replaceParams(this.replaceTemplate,params);
    }

    protected String replaceParams(String replaceTemplate,Map<String,String> params)
    {

        for (Map.Entry<String,String> param :this.templateParams.entrySet()) {
            String key = param.getKey();
            String value = "";
            if (params.containsKey(param.getKey())) {
                value = params.get(param.getKey());
            }

            replaceTemplate = replaceTemplate.replace("{" +key +"}",value);
        }

        return replaceTemplate;
    }

    /*
    {m} 输出代码中指定的消息

%p 输出优先级，即DEBUG，INFO，WARN，ERROR，FATAL

%r 输出自应用启动到输出该log信息耗费的毫秒数

%c 输出所属的类目，通常就是所在类的全名

%t 输出产生该日志事件的线程名

%n 输出一个回车换行符，Windows平台为“rn”，Unix平台为“n”

        %d 输出日志时间点的日期或时间，默认格式为ISO8601，也可以在其后指定格式，比如：%d{yyyy MMM dd HH:mm:ss,SSS}，输出类似：2002年10月18日 22：10：28，921

        %l 输出日志事件的发生位置，包括类目名、发生的线程，以及在代码中的行数

        */

}
